package cn.bonoon.kernel.web.models;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.batatasframework.web.RequestParameterReader;

import cn.bonoon.kernel.menus.ChannelDefinition;
import cn.bonoon.kernel.menus.DescribeDefinition;
import cn.bonoon.kernel.menus.MenuDefinition;
import cn.bonoon.kernel.menus.ModuleDefinition;
import cn.bonoon.kernel.menus.ModuleManager;
import cn.bonoon.kernel.menus.ServerResourceResolver;
import cn.bonoon.kernel.menus.StyleDefinition;
import cn.bonoon.kernel.menus.TabsDefinition;
import cn.bonoon.kernel.menus.privileges.PrivilegeInspector;
import cn.bonoon.kernel.menus.tips.MenuTipHandler;
import cn.bonoon.kernel.menus.tips.MenuTipResult;
import cn.bonoon.kernel.support.IOperator;
import cn.bonoon.kernel.util.StringHelper;

/**
 * <pre>
 * 需要生成整个界面的框架信息，包括：用户信息、频道栏、菜单、头部、尾部等框架信息
 * </pre>
 * 
 * 这个类需要进行大手术
 * 
 * 20170919  大改这个类
 * 
 * @author jackson
 * 
 */
public final class LayoutModel extends PanelModel {
	
	private final static String DEFAULT_LAYOUT_NAME = "lom";
	private final static String DEFAULT_LAYOUT_MASTER = "layout-admin.vm";
	private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E");

	private String menuTitle = "功能菜单";
	
	private String navigationTitle;
	
//	private String styleKey = "default";
//	private String descriptor;
//	private String desHref;
//	private int desHeight;
	
	private String menuOnClick;

	private StringBuilder eastWorkspace;
	private ContextMenuItem[] cmItems;
	
	private final String home;
//	private final StringBuilder fastNavi;
	private final StringBuilder menuSpace = new StringBuilder();
	private final StringBuilder channelItems = new StringBuilder();
	private final StringBuilder menuItems = new StringBuilder();
	
	/** 对应的get方法为：{@link #getStyle()} */
	private StyleDefinition style;

	private DescribeDefinition describe;

	public boolean isHasDocument(){
		return null != describe && describe.isShowDocument();
	}
	
	/**
	 * 初始化整个界面的样式，基础框架等！
	 * 
	 * @param title
	 *            导航位置信息
	 * @param module
	 *            子系统
	 * @param config
	 */
	public void initLayout(String title, StyleDefinition style, DescribeDefinition describe/*StyleGetter styleGetter*/) {
		this.navigationTitle = title;
		this.style = style;
		this.describe = describe;
//		if (null != describe) {
//			this.desHeight = describe.getHeight();
//			if (describe.isHref()) {
//				this.desHref = describe.getValue();
//			} else {
//				this.descriptor = describe.getValue();
//			}
//		}
	}
	
	@Override
	public StandardModel execute(String view) {
		if (menuItems.length() > 0) {
			menuSpace.append("<div title='").append(menuTitle);
			menuSpace.append("' data-settings=\"zone:'west', split:true, iconClassname:'icon-computer'\" style='width:");
			menuSpace.append(style.getMenuWidth()).append("px;'>");
			
			String south = buildSouth();
			if (null != south) {
				menuSpace.append("<div class='bupborderlayout' fit='true'>").append(south);
				menuSpace.append("<div data-settings=\"zone:'center', border:false\" style='padding:0px;margin:0px;'>");
				initMenus(menuSpace, block);
				menuSpace.append("</div></div>");
			} else {
				initMenus(menuSpace, block);
			}
			
			menuSpace.append("</div>");
		}
		return super.execute(view);
	}

	private void initMenus(StringBuilder menuSpace, StringBuilder block) {
		menuSpace.append("<ul id='tree-sys-menus'>").append(menuItems).append("</ul>");
//		if (null != cmItems && cmItems.length > 0) {
//			
//			block.append("jQuery('#cm-tree-sys-menus').__menu([");
//			cmItems[0].parse(menuSpace, block);
//			for (int i = 1; i < cmItems.length; i++) {
//				cmItems[i].parse(menuSpace, block.append(','));
//			}
//			block.append(']');
//			
//			if (StringHelper.isNotEmpty(menuOnClick)) {
//				block.append(",function(menuButton){").append(menuOnClick).append("});");
//			} else {
//				block.append(");");
//			}
//		} else if (StringHelper.isNotEmpty(menuOnClick)) {
//			block.append("jQuery('#tree-sys-menus').__menu(function(menuButton){").append(menuOnClick).append("});");
//		} else {
			block.append("jQuery('#tree-sys-menus').__menu();");
//		}
	}

	public static class ContextMenuItem {
		private final String name;
		private final String event;
		private String icon;

		public ContextMenuItem(String name, String event) {
			this("", name, event);
		}

		public ContextMenuItem(String icon, String name, String event) {
			this.name = name;
			this.event = event;
			this.icon = icon;
		}

		void parse(StringBuilder cm, StringBuilder ev) {
			cm.append("<div data-settings=\"iconClassname:'").append(icon).append("'\">");
			cm.append(name).append("</div>");
			ev.append("{name:'").append(name).append("',event:function(){").append(event).append("}}");
		}
	}

	/** 点击事件的处理 */
	public void menuContextMenu(ContextMenuItem... cmItems) {
		this.cmItems = cmItems;
	}

	public void setMenuOnClick(String menuOnClick) {
		this.menuOnClick = menuOnClick;
	}

	private String buildSouth() {
		return null;
	}

	public LayoutModel(String mid, HttpServletRequest request, ModuleManager manager) {
		super(mid, request, DEFAULT_LAYOUT_MASTER);
		this.resourceResolver = manager.getResourceServer();
		this.home = manager.getEndpoint();
		setModelName(DEFAULT_LAYOUT_NAME);
	}

	public void eastWorkspace(String title, String href, int width, boolean collapsed, StringBuilder east) {
		eastWorkspace = new StringBuilder("<div data-settings=\"zone:'east'\"");
		if (StringHelper.isNotEmpty(title)) {
			eastWorkspace.append(" title='").append(title);
		}
		if (StringHelper.isNotEmpty(href)) {
			eastWorkspace.append(" href='").append(href);
		}
		if (width < 100)
			width = 250;
		eastWorkspace.append("' id='eastWorkspace' style='width:").append(width).append("px;' collapsed='")
				.append(collapsed ? "true" : "false").append("'>");
		if (null != east) {
			eastWorkspace.append(east);
		}
		eastWorkspace.append("</div>");
	}

	public String getDay() {
		return sdf.format(new Date());
	}

	public StringBuilder getEastWorkspace() {
		return eastWorkspace;
	}

//	public String getDescriptor() {
//		return descriptor;
//	}

	public StyleDefinition getStyle() {
		return style;
	}

	/**
	 * 可以追加菜单
	 */
	public void menuItem(StringBuilder item) {
		if (null != item) {
			this.menuItems.append(item);
		}
	}

	public void menuItem(StringBuilder item0, String item1) {
		this.menuItems.append(item0).append(item1);
	}

	public void menuItem(String item) {
		this.menuItems.append(item);
	}

	public void menuItem(String item0, String item1) {
		this.menuItems.append(item0).append(item1);
	}

	public void menuItem(String item0, String item1, String item2) {
		this.menuItems.append(item0).append(item1).append(item2);
	}

	public StringBuilder menuBuilder() {
		return menuItems;
	}

	public String getNavigationTitle() {
		return navigationTitle;
	}

	public LayoutModel setMenuTitle(String menuTitle) {
		if (StringHelper.isNotEmpty(menuTitle)) {
			this.menuTitle = menuTitle;
		}
		return this;
	}

//	public String getDesHref() {
//		return desHref;
//	}

//	public StringBuilder getFastNavi() {
//		return fastNavi;
//	}

	public String getHome() {
		return home;
	}

//	public int getDesHeight() {
//		return desHeight;
//	}

//	public String getStyleKey() {
//		return styleKey;
//	}
//
//	public void setStyleKey(String styleKey) {
//		if (StringHelper.isNotEmpty(styleKey)) {
//			this.styleKey = styleKey;
//		}
//	}


	public StringBuilder getMenuSpace() {
		return menuSpace;
	}
	
	/** 以下是静态资金的指定方式，可以通过配置文件进行定义，资金静态资金服务器来处理这些静态资源 */
	private final ServerResourceResolver resourceResolver;
	
	public String resource(String path){
		return resourceResolver.resource(path);
	}

	public String path(String path){
		return resourceResolver.path(path);
	}
	
//	public String js(String path){
//		return path;
//	}
//	public String css(String path){
//		return path;
//	}
//	public String image(String path){
//		return path;
//	}
	public StringBuilder getChannelItems() {
		return channelItems;
	}
	
//	private class HomeButton implements MenuButtonAttribute{
//
//		@Override
//		public boolean selected(String selectedId) {
//			return StringHelper.isEmpty(selectedId);
//		}
//		
//	}

	public void buildChannel(ModuleDefinition module, IOperator user, RequestParameterReader reader, PrivilegeInspector privilege, String selected) throws Exception {
		List<ChannelDefinition> cis = module.getChannels(user, privilege);
		
		// 返回界面，显示不同标题图片
		this.addObject("userName", user.getUsername());
		this.addObject("moduleName", module.getName());
		
		channelItems.append("<li");
		String channelClass = "";
		if (StringHelper.isEmpty(selected)) {
			if (cis.isEmpty()) {
				channelItems.append(" class='lastChannelSelected'");
			} else {
				channelItems.append(" class='channelSelected'");
				channelClass = " class='afterSelected'";
			}
		}
		channelItems.append("><a href='").append(module.getEndpoint()).append("'><span>首页</span></a></li>");
		int i = 0;
		for (ChannelDefinition channel : cis) {
			i++;
			channelItems.append("<li");
			if (channel.selected(selected)) {
				if (i == cis.size()) {
					channelItems.append(" class='lastChannelSelected'");
				} else {
					channelItems.append(" class='channelSelected'");
					channelClass = " class='afterSelected'";
				}
			} else {
				channelItems.append(channelClass);
			}
			channelItems.append('>');
			// TODO 如果channel下没有定义访问的路径，则应该使用子菜单下第一个有访问权限的子菜单来显示
			channel.button(privilege, channelItems);
			
			MenuTipHandler tipHandler = channel.tipHandler();
			if(null != tipHandler){
				MenuTipResult tip = tipHandler.handle(user, reader);
				if(!tip.isEmpty()){
					channelItems.append("<span");
					if(tip.isShowTip()){
						channelItems.append(" title='").append(tip.getTip()).append("'");
					}
					channelItems.append(">").append(tip.getContent()).append("</span>");
				}
			}
			
			channelItems.append("</li>");
		}
	}

	public void buildMenu(IOperator user, RequestParameterReader reader,
			ChannelDefinition channel, PrivilegeInspector privilege, 
			String selected) throws Exception {
		StringBuilder icon_menu = new StringBuilder("<style type='text/css'>");
		StringBuilder mi = menuHtml(user, reader, channel.getMenus(), selected, privilege, icon_menu);
		if (null != mi && mi.length() > 0) {
			menuItems.append(mi);
		}
		// 如果是tabs则应该在频道的菜单最后面追加
		for (TabsDefinition tsi : channel.getTabs()) {
			if (privilege.hasPrivilege(tsi)) {
				menuItems.append("<li data-settings=\"iconClassname:'icon-menu'\"><span>");
				if (tsi.selected(selected)) {
					tsi.button(menuItems, "menuSelected");
				} else {
					tsi.button(menuItems, "");
				}
				menuItems.append("</span></li>");
			}
		}
		this.addObject("icon_menu", icon_menu.append("</style>"));
	}

	private StringBuilder menuHtml(
			IOperator user, RequestParameterReader reader,
			List<MenuDefinition> menus, 
			String sid, PrivilegeInspector privilege, 
			StringBuilder icon_menu) throws Exception {
		if (null == menus) { return null; }
		
		StringBuilder ul = new StringBuilder();

		for (MenuDefinition menu : menus) {
			StringBuilder subul = menuHtml(user, reader, menu.getMenus(), sid, privilege, icon_menu);

			String iconCls = menu.getIconCls();
			boolean bl_icon = StringHelper.isNotEmpty(iconCls);
			String menu_id = menu.getId();
			if (bl_icon) {
				icon_menu.append(".icon-menu-").append(menu_id).append("{background:url('").append(iconCls).append("') no-repeat; background-size:contain;}");
			}

			// 是否有操作的权限
			if (privilege.hasPrivilege(menu)) {
				// 是否应该设置为选中状态,如果选择的菜单ID相同
				boolean selected = menu.selected(sid);
				
				if (bl_icon){
					ul.append("<li data-settings=\"iconClassname:'icon-menu-").append(menu_id).append("'\">");
				}else{
					ul.append("<li data-settings=\"iconClassname:'icon-menus'\">");
				}

				button(user, reader, ul, menu, selected);
				
				if (null != subul && subul.length() > 0) {
					// 有下级子菜单的情况
					// 显示的文本内容
					ul.append("<ul>").append(subul).append("</ul>");
//				} else {
//					// 没有下级的子菜单的情况
//					// 显示的文本内容
//					button(user, reader, ul, menu, selected);
				}

				ul.append("</li>");
			} else if (null != subul && subul.length() > 0) {
				// 有下级子菜单的情况
				// 功能显示该菜单,但不能对该菜单进行操作
				if (bl_icon){
					ul.append("<li data-settings=\"iconClassname:'icon-menu-").append(menu_id);
					ul.append("'\"><span><a href='javascript:void(null);'>").append(menu.getName());
					ul.append("</a></span><ul>").append(subul).append("</ul></li>");
				}else{
					ul.append("<li data-settings=\"iconClassname:'icon-menus'\">");
					ul.append("<span><a href='javascript:void(null);'>").append(menu.getName());
					ul.append("</a></span><ul>").append(subul).append("</ul></li>");
				}
			} else {
				continue;
			}
		}
		return ul;
	}

	private StringBuilder button(IOperator user, RequestParameterReader reader,
			StringBuilder a, MenuDefinition menu, boolean selected) throws Exception {
		a.append("<span>");
		if (selected) {
			menu.button(a, "menuSelected ");
		} else {
			menu.button(a, "");
		}

		MenuTipHandler tipHandler = menu.tipHandler();
		if(null != tipHandler){
			MenuTipResult tip = tipHandler.handle(user, reader);
			if(!tip.isEmpty()){
				a.append("<span");
				if(tip.isShowTip()){
					a.append(" title='").append(tip.getTip()).append("'");
				}
				a.append(">").append(tip.getContent()).append("</span>");
			}
		}
		
		return a.append("</span>");
	}
}
